/**
 * Copyright  2025, Hai Yue Xing He Technology Co., Ltd
 * 
 * @author        ZHAO LIMIN
 * @version       1.0.1
 * @since         2025-04
 * SpritePlayer.ts  精灵操作类   
 */
import { _decorator, Component,  KeyCode, Node } from 'cc';
import { Cion } from './cion';
import { defined } from '../hyxh/core/Defined';
import { Cartesian3 } from '../hyxh/core/Cartesian3';
import { SecenseTools } from './SecenseTools';
import { IParametersOptions } from '../hyxh/core/HBase';
import { Check } from '../hyxh/core/Check';
import { ICartesian } from '../hyxh/core/Cartesian';
import { SecenesManager } from './SecenesManager';
import { HImageResource } from './HResource';
import { ElevatorController } from './ElevatorController';
const { ccclass, property } = _decorator;

export enum ESPRITE_STATE {
    UNKNOWN = 0,   /* 未知 */
    IDLE = 1,      /* 空闲 */
    RUN = 2,       /* 运行 */
    LOST = 3,      /* 丢失，被捕捉 */
    FAILURE = 4   /* 失败 */
}

@ccclass('SpritePlayer')
export class SpritePlayer extends Component { 
    /* 默认为3个，根据配置来处理，并现在是TopWin 上 */
    private _conf_life_number: number = 3;
    /* 在活次数 */
    private _life_count = 0;
    
    @property('thisnode')
    private thisNode: Node = null;

    private _spriteFrame: HImageResource = null!;
    private _spriteFrame_down: HImageResource = null!;
    private _spriteFrame_up: HImageResource = null!;
    private _spriteFrame_left: HImageResource = null!;
    private _spriteFrame_right: HImageResource = null!;    
    /* 改成rid */
    private _image_url = 0;
    private _image_down_url = 0;
    private _image_up_url = 0;
    private _image_left_url = 0;
    private _image_right_url = 0;

    private _startPosition : ICartesian = null;
   
    @property('seceneController')
    private _secenController: SecenseTools = null!;
   
   
    /* 位置信息 */
    private _node_pos: Cion = null!;

    private _current_key_code = 0;

    private speedTime = 0.00;
    private stime = 0.00;

    private isRun = false;
    /* 活跃状态 */
    private isActive = true;
    /* 在电梯上 */    
    private onboardElevator = false;
    /* 精灵所在电梯 */
    private pass_for_elevator = null;
    /* 精灵等待电梯 */
    private _waitting_for_elevator = null;

    /* 设置精灵的State, 用于 */
    spriteState: ESPRITE_STATE = ESPRITE_STATE.UNKNOWN;

    /* 事件 */
    public onEventForCatchCion:(spritePlay:SpritePlayer) =>void;

    /* 发出正在移动 */
    public onEventForMovePos:(secenTools: SecenseTools) =>void;

    public spriterun() {
        this.isRun = true;
        this.stime = 0.00; 
        this.spriteState = ESPRITE_STATE.RUN;
    }
    public spritestop() {
        this.isRun = false;
        this.stime = 0.00; 
        this._current_key_code = -1; 
        this.spriteState = ESPRITE_STATE.IDLE;    
        /* 移动事件取消 */
        this.onEventForMovePos = null;   
    }

    public isStop() {
        return !this.isRun && (this.spriteState != ESPRITE_STATE.RUN);
    }

    public spriteNoLife() {
        this.isActive = false;
        SecenesManager.hideImage(this.thisNode);
        this.onEventForCatchCion = null;
        this.onEventForMovePos = null;
    }
    /**
     * 表示精灵是否在线，及在SecentTools 中
     */
    public spriteOnline() {
        this.spriteState = ESPRITE_STATE.RUN;
    }
    public spriteIdle () {
        this.spriteState = ESPRITE_STATE.IDLE;
    }
    /**
     * 精灵被抓到
     */
    public spriteBeTaked () {
        this.spriteState = ESPRITE_STATE.LOST;
    }
    public setSeceneController(secenController: SecenseTools) {
        this._secenController = secenController; 
    }

    public getSeceneController() : SecenseTools{
        return this._secenController;
    }

    public spriteLife() {
        this.isActive = true;
        this.spriteShow();
        if (!defined(this._secenController)) {
            return;
        }

        if (defined(this._secenController.backAutoSource)){
            this._secenController.backAutoSource.play();
        }
    }

    public spriteShow() {
        SecenesManager.unhideImage(this.thisNode);
    }

    public spriteNoShow() {
        SecenesManager.hideImage(this.thisNode);
    }

    /* 电梯 */
    public isOnboardElevator() {
        return this.onboardElevator;
    }

    public isOnBoardElevatorActivity(): boolean {
        if (defined(this.pass_for_elevator)) {
            return this.pass_for_elevator.isActivity();
        }
        return false;
    }

    public setOnboardElevator(onboardElevator: boolean) {
        this.onboardElevator = onboardElevator;
    }

    public forLeaveOnboardElevator(_next_pos: Cion): boolean {
        if (!defined(this.pass_for_elevator)) {
            return true;
        }
        if (!defined(_next_pos)) {
            return true;
        }
        return this.pass_for_elevator.nextPosForLeaveElevator(_next_pos);
    }

    public onboard(elevator: ElevatorController) {
        this.onboardElevator = true;
        this.pass_for_elevator = elevator;
        this.pass_for_elevator.setPassenger(this);
        this.pass_for_elevator.generateElevatorPathForRunElevator();
        this.pass_for_elevator.runElevator();
    }

    public offboard() {
        if (defined(this.pass_for_elevator)) {
            /* 乘客离开电梯 */
            this.pass_for_elevator.passengerLeave();
        }
        this.onboardElevator = false;
        this.pass_for_elevator = null;
    }

    /**
     * "sprite":{
     *       "name":"sprite",
     *       "image":"spirit/spirit_dw",
     *       "imageDown":"spirit/spirit_dw_smll",
     *       "imageUp":"spirit/spirit_up_smll",
     *       "imageLeft":"spirit/spirit_left_smll",
     *       "imageRight":"spirit/spirit_right_smll",
     *       "startPosition":[5.3,-330.0, 0.0],
     *       "width": 32,
     *       "height": 32
     *   },
     * @param option 初始化， 根据JSON 的配置
     */
    public initialize(option: IParametersOptions) {
        Check.defined("option", option);
        this.name = option.name??"spirit9001";
        this._image_url = option.image?? 9001001;
        this._image_down_url= option.imageDown??9001002;
        this._image_up_url =  option.imageUp??9001003;
        this._image_left_url = option.imageLeft??9001004;
        this._image_right_url = option.imageRight??9001005; 
        this.speedTime = option.speedTime?? 0.00;
        
        this._conf_life_number = option.lifeNumber?? 3;
        this._life_count = 0;
      
        this.thisNode = new Node(this.name);
        this.thisNode.setParent(this.node); // 将节点添加到场景中
        if (defined(option.startPosition)) {
            const _x = option.startPosition[0]?? 0.0;
            const _y = option.startPosition[1]?? 0.0;
            const _z = option.startPosition[2]?? 0.0; 
            this._startPosition = new Cartesian3(_x, _y, _z);
            this.thisNode.setPosition(this._startPosition.x, this._startPosition.y, this._startPosition.z); // 设置节点的位置                    
        }
        
    }  
   
    public initSpriteImages() {
        this._spriteFrame = SecenesManager.getInstance().getResource(this._image_url) as HImageResource;
        this._spriteFrame_down = SecenesManager.getInstance().getResource(this._image_down_url) as HImageResource;
        this._spriteFrame_up = SecenesManager.getInstance().getResource(this._image_up_url) as HImageResource;
        this._spriteFrame_left =  SecenesManager.getInstance().getResource(this._image_left_url) as HImageResource;
        this._spriteFrame_right = SecenesManager.getInstance().getResource(this._image_right_url) as HImageResource;
    }
    /* 定位 */
    public location(location_x: number, location_y:number, location_z:number) {
        this.thisNode.setPosition(location_x, location_y, location_z ); // 设置节点的位置        
    }

    public loadResources() {    
        this.initSpriteImages(); 
        SecenesManager.showImage(this.thisNode, this._spriteFrame);
    }
    
    update(deltaTime: number) {
        this.activeMovenext(deltaTime);
    }
    /**
     * 或者月
     */
    private activeMovenext(deltaTime: number) {
        
        if (!this.isActive){
            return;
        }
        if (this.isStop()) {
            return;
        }
        
        this.stime += deltaTime;
        if ( this.stime >= this.speedTime ){
            this.stime = 0;
            if (this.isRun && (!this.isStop())) {
                this.moveNextPosition();
            }
        }
        switch(this._current_key_code) {
            case KeyCode.ARROW_DOWN:     
                if(!defined(this._spriteFrame_down) ){
                    return;
                }               
                SecenesManager.showImage(this.thisNode, this._spriteFrame_down);
                return;
            case KeyCode.ARROW_UP:
                if(!defined(this._spriteFrame_up) ){
                    return;
                }
                SecenesManager.showImage(this.thisNode, this._spriteFrame_up);
                return;
            case KeyCode.ARROW_LEFT:
                if(!defined(this._spriteFrame_left) ){
                    return;
                }
                SecenesManager.showImage(this.thisNode, this._spriteFrame_up);
                return;
            case KeyCode.ARROW_RIGHT:
                if(!defined(this._spriteFrame_right) ){
                    return;
                }
                SecenesManager.showImage(this.thisNode, this._spriteFrame_up);
                return;
            default:
                if(!defined(this._spriteFrame) ){
                    return;
                }
                SecenesManager.showImage(this.thisNode, this._spriteFrame_up);
        }        
    }
    /**
     * 移动下一个位置
     * @param keyCode 
     */
    public movenext(keyCode: number) {
        this._current_key_code = keyCode;
    }
    public moveForNodePos(new_node_pos: Cion) {
        if(!SecenseTools.LOCL_SIGN) {
            SecenseTools.LOCL_SIGN = true;
            try {        
                if (!defined(new_node_pos)) {
                    return;
                }
                this._node_pos = new_node_pos;
                this.thisNode.setPosition(this._node_pos.position.x, this._node_pos.position.y, this._node_pos.position.z);

                if (defined(this.onEventForCatchCion)){
                    this.onEventForCatchCion(this);    
                }
                this._node_pos.releaseSprite();
            }catch(error){
                console.error(error);
            }finally{
                SecenseTools.LOCL_SIGN = false;
            }
        }
    }

    private is_cause = false;

    /**
     * 当前位置是否等待，位置，并且能登上电梯
     */    
    isWaittingForElvator(): boolean {
        if (!defined(this._secenController)) {
            return false;
        }
        if (!defined(this._waitting_for_elevator)) {
            return false;
        }
        if (!defined(this._node_pos)) {
            /* 在开始位置 */
            return false;
        }
        if (this._waitting_for_elevator.isActivity()) {
            return false;
        }
        if (defined(this._waitting_for_elevator.hasPassenger())) {
            return false;
        }
        return true;
    }

    private nowaittingElevator() {
        this._waitting_for_elevator = null;
    }

    public moveNextPosition() { 
        if(!defined(this._secenController)) {
            return;
        }

        if (!defined(this._node_pos) ) {
            /* 在开始位置 */
            this.is_cause = false;
            this._node_pos = this._secenController.findNearestPoint(new Cartesian3(
                this.thisNode.position.x, 
                this.thisNode.position.y, 
                this.thisNode.position.z));
            if(!defined(this._node_pos)) {
                return; 
            }
            return;
        } 
        

        if (!this.is_cause) {
            /* 判断是否在十字路口 */
            if( this._secenController.isCrossPoint(this._node_pos) ) {
                this.is_cause = true;
                return; 
            }
        }         
        if (this._current_key_code <= 0 ){
            return;
        }

        const _new_node_pos = this._secenController.findNextPosition(this._node_pos, this._current_key_code);
        if (!defined(_new_node_pos)) {
            return;
        }
        if ((_new_node_pos == this._node_pos) ||
            (_new_node_pos.equalsPosition(this._node_pos))) {
            return;
        }

        if (this.isOnboardElevator() && this.isOnBoardElevatorActivity()) {
            /* 精灵正在运输中 */
            return;
        } else if (this.isOnboardElevator() && 
                    !this.isOnBoardElevatorActivity()) {
            /* 精灵已经停止 */
            if ( this.forLeaveOnboardElevator(_new_node_pos)) {
                /* 如果指向正在运行的电梯，则停止 */
                this.moveForNodePos(_new_node_pos);
                /* 离开电梯 */
                this.nowaittingElevator();                
                this.offboard();
                return;
            }
            return;
        } else if (!this.isOnboardElevator()) {
            /* 精灵没有在电梯上 */
            if (defined(this._waitting_for_elevator)) {
                if (!this._waitting_for_elevator.isActivity() &&
                    this._waitting_for_elevator.nextPosForElevator(_new_node_pos)) {
                    this.onboard(this._waitting_for_elevator);
                    this.nowaittingElevator();
                    return;
                } 
            }
        }
        this.is_cause = false;
        /* 移动到下一个为止 */
        this.moveForNodePos(_new_node_pos);
        this.nowaittingElevator();
        this.offboard();
        /* 是否到了电梯位置, 激活电梯，到指定位置 */
        if (this.touchElevator() ){
            return;
        }
        /* 传送门操作 */
        if (this.enterStageForTransmit()) {
            return;
        }      

    }
    /**
     * 精灵进入传送阵
     * @returns 
     */
    public enterStageForTransmit() :boolean  {
        if (!defined(this._secenController)) {
            return false ;
        } 
         /* 判断是否进入传送门 */
        const stageController = this._secenController.judgeEnterStage(this);
        if (defined(stageController)) {
            const new_stage = this._secenController.transmitToStage(stageController);
            if (defined(new_stage)) {
                this.moveForNodePos(new_stage.getNodePos());
            }
            return true;
        }    
        return false;
    }

    public touchElevator() : boolean {
        if (!defined(this._secenController)) {
            return false ;
        }        
        /* 根据网络拓扑确定，附近是否有电梯， 如果有，电梯移动到等待位置 */
        if ( this._secenController.isTouchElevator(this._node_pos) ) {
            /* 当前电梯，根据接触cion 及Node_pos 判断是否在精灵接触的位置上，如果不是 */
            this._waitting_for_elevator = this._secenController.findNextPositionForElevator(this._node_pos);
            if (!defined( this._waitting_for_elevator)) {
                return;
            }
            /* 启动电梯 */ 
            this._waitting_for_elevator.generateElevatorPath(this._node_pos);
            return true;
        }
        return false;
    }


    public getNodePosition() : Cion | null{
        return this._node_pos;
    }

    public setNodePosition(new_pos:  Cion){
        if ( !defined(new_pos)) {
            return; 
        }
        this._node_pos = new_pos;
        this.thisNode.setPosition(this._node_pos.position.x, this._node_pos.position.y, this._node_pos.position.z); 
    }

    public getPositionIndices() : Array<number>{
        if (!defined(this._node_pos)) {
            return [];
        }
        return this._node_pos.firstPoint();        
    } 


}


